package pers.jsan.litheopen.security.prover;

import org.springframework.stereotype.Component;
import pers.jsan.litheopen.security.config.SpringContextHelper;
import pers.jsan.litheopen.security.exception.LitheAuthenticationException;
import pers.jsan.litheopen.security.oauth.model.LitheAuthenticationToken;
import pers.jsan.litheopen.security.oauth.model.UserDetail;
import pers.jsan.litheopen.security.oauth.service.IUserDetailService;
import pers.jsan.litheopen.utils.MD5Util;

import java.util.Map;

@Component
public class LitheAuthenticationProver implements AuthenticationProver {

    private IUserDetailService userDetailService;

    public LitheAuthenticationToken authenticate(LitheAuthenticationToken litheAuthenticationToken) throws LitheAuthenticationException {
        //获取校验信息
        String loginName = (String) litheAuthenticationToken.getPrincipal();
        //获取用户信息方法
        Map<String, ? extends IUserDetailService> serviceMap = SpringContextHelper.getApplicationContext().getBeansOfType(userDetailService.getClass());
        if(serviceMap.size() == 0) {
            throw new LitheAuthenticationException("找不到获取用户信息方法");
        }
        IUserDetailService userDetailService = serviceMap.get(serviceMap.keySet().iterator().next());
        //读取用户信息
        UserDetail userDetail = userDetailService.loadUserMessage(loginName);
        //校验密码
        if(!MD5Util.encryption32(userDetail.getSalt()+MD5Util.encryption32((String) litheAuthenticationToken.getCredentials())).equals(userDetail.getPassword())) {
            throw new LitheAuthenticationException("密码不正确");
        }
        //返回凭证信息
        userDetail.setPassword(null);
        userDetail.setSalt(null);
        return new LitheAuthenticationToken(userDetail, null);
    }

    @Override
    public Object formatOauthUserMessage(UserDetail userDetail) {
        Map<String, ? extends IUserDetailService> serviceMap = SpringContextHelper.getApplicationContext().getBeansOfType(userDetailService.getClass());
        if(serviceMap.size() == 0) {
            return userDetail;
        }
        IUserDetailService userDetailService = serviceMap.get(serviceMap.keySet().iterator().next());
        return userDetailService.formatOauthUserMessage(userDetail);
    }

    public LitheAuthenticationProver setUserDetailService(IUserDetailService userDetailService) {
        this.userDetailService = userDetailService;
        return this;
    }
}
